/***********************************************************************************
 * 文件名： rt_port.c
 * 作者： 刘言
 * 版本： 1
 * 说明：
 * 		RT-Thread 移植文件，这里实现了一些移植需要的函数。
 * 修改记录：
 * 	2023/06/02: 初版。 刘言。
***********************************************************************************/
#include "board.h"
#include "rtthread.h"
#include <stdio.h>

#if APP_DRIVE_SELECT == 0

#ifdef RT_USING_CONSOLE
static rt_sem_t mSemCin;	// 使用信号量来阻塞 finsh 线程
#endif

/**
 * rtthread_startup 首先调用的函数，此函数几乎可以认为上电就运行（前面还有MDK特有的SystemInit）。
*/
void rt_hw_board_init(void)
{
    // SysTick_Config(SystemCoreClock / RT_TICK_PER_SECOND);   /* 10ms */ // 稍后初始化：Polsys_Init->Mcu_TickStart
#ifdef RT_USING_HEAP
    rt_system_heap_init(HEAP_BEGIN, HEAP_END);
#endif
#ifdef RT_USING_CONSOLE
    mSemCin = rt_sem_create("cin", 0, RT_IPC_FLAG_PRIO);
    Board_InitConsoleDevice();  // 需要先单独初始化console使用的设备，如果用 rt_components_board_init 初始化将无法打印初始化信息。
#endif
#ifdef RT_USING_COMPONENTS_INIT
    // 如果想要打印初始化信息，需要确保在此之前 console 已经可以正常打印。
    rt_components_board_init();
#endif
}

/**
 * 重定义 rt_hw_console_output 使用标准输出.
 * 当没有给console指定一个设备时，实现 rt_hw_console_output 后才能打印信息。
 * 注意：当给 console 指定了一个设备后，此函数无意义。
*/
void rt_hw_console_output(const char *str)
{
    while(*str != '\0')
    {
        Uart_WriteByte(&ConsoleUart, *str++);
    }
}

/**
 * 官方介绍：控制台获取一个字符，即在该函数中实现 uart 获取字符，可以使用查询方式获取（注意不要死等，在未获取到字符时，需要让出 CPU），推荐使用中断方式获取。
 * 当不使用DEVICE时，实现 rt_hw_console_getchar 后才能使用finsh获取命令输入。
 * 注意：开启 RT_USING_DEVICE 后此函数无意义，必须给console指定一个设备。
*/
char rt_hw_console_getchar(void)
{
    rt_sem_take(mSemCin, RT_WAITING_FOREVER); // 阻塞线程，等待串口收到数据
	return Uart_ReadByte(&ConsoleUart);
}

// 中断事件：Console 串口收到一个字节
void RtPort_EvConsoleReceivedByte()
{
    rt_sem_release(mSemCin);	// 释放信号量，rt_hw_console_getchar 继续执行，处理串口收到的数据。
}

#else   // 使用标准RTT设备作为 console 输出设备

/**
 * rtthread_startup 首先调用的函数，此函数几乎可以认为上电就运行（前面还有MDK特有的SystemInit）。
*/
void rt_hw_board_init(void)
{
    // SysTick_Config(SystemCoreClock / RT_TICK_PER_SECOND);   /* 10ms */ // 稍后会在MCU驱动中初始化：Polsys_Init->Mcu_TickStart->SysTick_Config
#ifdef RT_USING_HEAP
    rt_system_heap_init(HEAP_BEGIN, HEAP_END);
#endif
    /* Pin driver initialization is open by default */
#ifdef RT_USING_PIN
    rt_hw_pin_init();
#endif
    /* USART driver initialization is open by default */
#ifdef RT_USING_SERIAL
    rt_hw_usart_init();
#endif
#ifdef RT_USING_CONSOLE
    rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
#endif
#ifdef RT_USING_COMPONENTS_INIT
    // 如果想要打印初始化信息，需要确保在此之前 console 已经可以正常打印。
    rt_components_board_init();
#endif
}

#endif



